package pluginUtils;

/**
 * A Doyle circle is basically a circle together with some specific information for
 * the generation of Doyle's spirals.
 * <ul>
 * <li> x,y center coordinates (double)</li>
 * <li> radius (double)</li>
 * <li> Angle of rotation (in order to place correctly the surrounding circles)</li>
 * <li> Powers of A and B (for efficient coloring : might also be used for radius computation)</li>
 * </ul>
 * @author Francesco
 *
 */

public class DoyleCircle implements Comparable<DoyleCircle>{
	protected double xcenter,ycenter,rotation,radius;
	protected int Apower,Bpower;
	static protected int ra,rb;
	static protected boolean boundSet=false; 
	static public void setBounds(int a,int b){
		ra=a; 
		rb=b; 
		boundSet=true;
	}

	protected String name=null; 
	public DoyleCircle(double xcenter, double ycenter, double rotation, double radius,int ap,int bp) {
		super();
		if(!boundSet){System.out.println("Must set bounds"); System.exit(0); }
		this.xcenter = xcenter;
		this.ycenter = ycenter;
		this.rotation = rotation;
		this.radius = radius;
		//while((ap>=ra)&&(bp>=rb)){ap-=ra; bp-=rb; }
		//while((ap<=-ra)&&(bp<=-rb)){ap+=ra; bp+=rb;}
		this.Apower=ap; 
		this.Bpower=bp; 
	}
	public DoyleCircle(Complexe z, double rotation, double radius,int ap,int bp) {
		super();
		if(!boundSet){System.out.println("Must set bounds"); System.exit(0); }
		this.xcenter = z.getReal();
		this.ycenter = z.getIm();
		this.rotation = rotation;
		this.radius = radius;
		//while((ap>=ra)&&(bp>=rb)){ap-=ra; bp-=rb; }
		//while((ap<=-ra)&&(bp<=-rb)){ap+=ra; bp+=rb;}
		this.Apower=ap; 
		this.Bpower=bp; 
	}
	
	public DoyleCircle(Circle c, double rotation,int ap,int bp) {
		super();
		if(!boundSet){System.out.println("Must set bounds"); System.exit(0); }
		this.xcenter = c.getCenter().getReal();
		this.ycenter = c.getCenter().getIm();
		this.rotation = rotation;
		this.radius = c.getRadius(); 
		//while((ap>=ra)&&(bp>=rb)){ap-=ra; bp-=rb; }
		//while((ap<=-ra)&&(bp<=-rb)){ap+=ra; bp+=rb;}
		this.Apower=ap; 
		this.Bpower=bp; 
	}
	
	
	
	public double getRadius() {
		return radius;
	}
	public void setRadius(double radius) {
		this.radius = radius;
	}
	public double getRotation() {
		return rotation;
	}
	public void setRotation(double rotation) {
		this.rotation = rotation;
	}
	public double getXcenter() {
		return xcenter;
	}
	public void setXcenter(double xcenter) {
		this.xcenter = xcenter;
	}
	public double getYcenter() {
		return ycenter;
	}
	public void setYcenter(double ycenter) {
		this.ycenter = ycenter;
	}
	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		/*long temp;
		temp = Double.doubleToLongBits(radius);
		result = PRIME * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(rotation);
		result = PRIME * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(xcenter);
		result = PRIME * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(ycenter);
		result = PRIME * result + (int) (temp ^ (temp >>> 32));
		*/
		return result;
	}
	
	public boolean equals1(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final DoyleCircle other = (DoyleCircle) obj;
		if (Double.doubleToLongBits(radius) != Double.doubleToLongBits(other.radius))
			return false;
		if (Double.doubleToLongBits(rotation) != Double.doubleToLongBits(other.rotation))
			return false;
		if (Double.doubleToLongBits(xcenter) != Double.doubleToLongBits(other.xcenter))
			return false;
		if (Double.doubleToLongBits(ycenter) != Double.doubleToLongBits(other.ycenter))
			return false;
		return true;
	}
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final DoyleCircle other = (DoyleCircle) obj;
		
		double dx=Math.abs(this.getXcenter()-other.getXcenter()); 
		double dy=Math.abs(this.getYcenter()-other.getYcenter());
		double dist=Math.sqrt(dx*dx+dy*dy);
		//System.out.println("**"+dx+" "+dy );
		//if(dist<0.999*(this.radius+other.radius)) return true; //DEBUG
		if(dist<0.99999*(this.radius+other.radius)) {
			return true;
		}
		//if((this.getXcenter()==other.getYcenter())&&(this.getYcenter()==other.getYcenter()))
			//return true; 
		//if((this.Apower==other.Apower)&&(this.Bpower==other.Bpower)) return true; 
		return false;
	}
	

	public int getApower() {
		return Apower;
	}
	public void setApower(int apower) {
		Apower = apower;
	}
	public int getBpower() {
		return Bpower;
	}
	public void setBpower(int bpower) {
		Bpower = bpower;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}

	public String toString(){
		String s="A :"+Apower+" B :"+Bpower+" radius "+radius;
		return s;
	}

	public int compareTo(DoyleCircle o) {
		if(this.radius<o.radius)return -1; 
		if(this.radius>o.radius) return 1; 
		double argthis=this.getXcenter()*this.getXcenter()+this.getYcenter()*this.getYcenter();
		double argo=o.getXcenter()*o.getXcenter()+o.getYcenter()*o.getYcenter();
		if(argthis<argo)return -1; 
		if(argo<argthis)return 1; 
		System.out.println("Cercles egaux :\n"+this+"\n"+o); 
		return 0;
	}
	
	public Circle getCircle(){
		return new Circle(Complexe.createComplexeFromRI(xcenter,ycenter),radius); 
	}
	
	
	
	
}
